package tool.mouse;

import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import tool.image.ImageTool;
import tool.keep.Keeper;
import tool.keyboard.KeyBoardTool;
import tool.paoshang.Luxian;
import tool.paoshang.PaoShang;
import tool.windows.W32API.HWND;
import tool.windows.WindowsTool;
import tool.windows.struct.LPRECTlpRect;

public class MouseTool {

	public static Point MH600ABSOLT = new Point(370,150);
	public static Point MH600WANDH = new Point(200,200);
	
	public static Point getMouseRealLocation(){
		return MouseInfo.getPointerInfo().getLocation();
	}

	public static void leftClick(){
		Keeper.getRobot().mousePress(MouseEvent.BUTTON1_MASK);
		Luxian.sleep(20);
		Keeper.getRobot().mouseRelease(MouseEvent.BUTTON1_MASK);
		Luxian.sleep(100);
	}

	public static void rightClick(){
		Keeper.getRobot().mousePress(InputEvent.BUTTON3_MASK);
		Luxian.sleep(20);
		Keeper.getRobot().mouseRelease(InputEvent.BUTTON3_MASK);
		Luxian.sleep(100);
	}
	
	public static void ctrlLeftClick(){
		KeyBoardTool.pressButton("ctrl");
		Luxian.sleep(20);
		leftClick();
		Luxian.sleep(20);
		KeyBoardTool.releaseButton("ctrl");
		Luxian.sleep(100);
	}

	public static void MoveTo(Point p){
		
		Point lastPoint = new Point(999,999);
		int time = 0;
		while(true){
			Point now = getMouseRealLocation();
			if(now.x==lastPoint.x && now.y == lastPoint.y) {
				time++;
			}else {
				lastPoint = now;
				time=0;
			}
			if(time>10) {
				throw new RuntimeException();
			}
			int movX = 0;
			int movY = 0;
			if(now.x>p.x){
				movX = -1;
			}else if(now.x<p.x){
				movX =1;
			}
			if(now.y>p.y){
				movY = -1;
			}else if(now.y<p.y){
				movY = 1;
			}
			if(movX == 0 && movY == 0){
				break;
			}
			Keeper.getRobot().mouseMove(now.x + movX, now.y + movY);
			Luxian.sleep(10);
		}
	}
	
	public static void MoveRelative(Point p){
		
		int x = p.x;
		int y = p.y;
		while(true){
			Point now = getMouseRealLocation();
			int xmove = 0;
			int ymove = 0;
			if(x>0) {
				x--;
				xmove = 1;
			}else if(x<0) {
				x++;
				xmove = -1;
			}else if(y==0){
				break;
			}
			if(y>0) {
				y--;
				ymove = 1;
			}else if(y<0) {
				y++;
				ymove = -1;
			}
			Keeper.getRobot().mouseMove(now.x + xmove, now.y + ymove);
			Luxian.sleep(10);
		}
	}
	
	public static void JumpTo(Point p){
		Keeper.getRobot().mouseMove(p.x, p.y);
	}
	
	public static Point findMouse(HWND hwnd){
		Point p =ImageTool.getWorldDifferent(hwnd);
		return p;
	}

	public static Point MoveRelative(HWND hwnd , Point p,Integer thresHold){
		return MoveRelative(hwnd,p,thresHold,0);
	}

	public static Point MoveRelative(HWND hwnd , Point p,Integer thresHold,int time){

		WindowsTool.getForce(hwnd);
		LPRECTlpRect rect = ImageTool.getClientRect(hwnd);
		KeyBoardTool.altClickButton("m");
		Luxian.sleep(300);
		Point firstP = new Point();
		if(p.x + 40 > Keeper.mhClintSize.x){
			firstP.x = p.x-40;
		}else if(p.x -40 < 0){
			firstP.x = p.x+40;
		}else{
			firstP.x = p.x;
		}
		if(p.y + 40 > Keeper.mhClintSize.y){
			firstP.y = p.y-40;
		}else if(p.y - 40 < Keeper.mhTitleHeight){
			firstP.y = p.y+40;
		}else{
			firstP.y = p.y;
		}
		firstP.x = firstP.x + rect.x;
		firstP.y = firstP.y + rect.y;
		JumpTo(firstP);
		Point nowP =null;
		while(true){
			Luxian.sleep(100);
			nowP = findMouse(hwnd);
			Point intervalP = new Point(p.x -nowP.x,p.y-nowP.y);
			if(Math.abs(intervalP.x)<=thresHold && Math.abs(intervalP.y)<=thresHold){
				break;
			}
			WindowsTool.moveMouseRelative(intervalP);
			if(Math.abs(intervalP.x)>80 || Math.abs(intervalP.y)>80) {
				KeyBoardTool.altClickButton("m");

				return MoveRelative(hwnd,p,thresHold,++time);
			}
			Point realP = getMouseRealLocation();
			Point moveP = new Point(realP.x+intervalP.x,realP.y+intervalP.y);
			try {
				MoveTo(moveP);
			}catch (RuntimeException e) {
				KeyBoardTool.altClickButton("m");
				Luxian.sleep(300);
				KeyBoardTool.altClickButton("m");
				Luxian.sleep(300);
			}
		}

		KeyBoardTool.altClickButton("m");
		Luxian.sleep(200);
		return nowP;
	}

	public static void MoveRelativeOnce(HWND hwnd , Point p){

		LPRECTlpRect rect = ImageTool.getClientRect(hwnd);
		Point firstP = new Point();
		if(p.x + 40 > Keeper.mhClintSize.x){
			firstP.x = p.x-40;
		}else if(p.x -40 < 0){
			firstP.x = p.x+40;
		}else{
			firstP.x = p.x;
		}
		if(p.y + 40 > Keeper.mhClintSize.y){
			firstP.y = p.y-40;
		}else if(p.y - 40 < Keeper.mhTitleHeight){
			firstP.y = p.y+40;
		}else{
			firstP.y = p.y;
		}
		firstP.x = firstP.x + rect.x;
		firstP.y = firstP.y + rect.y;
		JumpTo(firstP);
		Luxian.sleep(50);
	}

	private static BufferedImage getAltWRect(HWND hwnd, LPRECTlpRect rect) {

		LPRECTlpRect altWRect = new LPRECTlpRect();
		altWRect.x = rect.x + MH600ABSOLT.x;
		altWRect.y = rect.y + MH600ABSOLT.y;
		altWRect.width = altWRect.x + MH600WANDH.x;
		altWRect.height = altWRect.y + MH600WANDH.y;
		Luxian.sleep(20);
		return ImageTool.getScreenShoot(altWRect);
	}
	
	public static boolean isDialogOpen(HWND hwnd) {
		int i =0;
		boolean check = false;
		while(i++<40) {
			Luxian.sleep(100);
			BufferedImage bi = ImageTool.getScreenShoot(hwnd);
			for(int j=0;j<Keeper.dialogXTop.length;j++) {
				if(bi.getRGB(Keeper.xTop.x, Keeper.xTop.y) == Keeper.dialogXTop[j]) {
					check = true;
					break;
				}
			}
			if(check) {
				for(int j=0;j<Keeper.dialogXTop.length;j++) {
					if(bi.getRGB(Keeper.xBottom.x, Keeper.xBottom.y) == Keeper.dialogXBottom[j]) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
}
